﻿namespace CardPlay.Model.GameModel.Actions
{
    public class GatherPileAction : GameAction
    {
        private int _totalMoved;

        public GatherPileAction(CardGame cardGame, PartLocation from, PartLocation to) : base(cardGame, from)
        {
            TargetLocation = to;
        }

        public PartLocation TargetLocation { get; private set; }

        protected override void OnExecute()
        {
            var sourcePile = CardGame.PileAt(Location);
            var targetPile = CardGame.PileAt(TargetLocation);

            var pile = sourcePile.SubPile(Location.Index, sourcePile.Count);
            pile.Invert();

            _totalMoved = pile.Count;

            targetPile.InsertCards(TargetLocation.Index, pile);
            sourcePile.RemoveCards(Location.Index, pile.Count);
        }

        protected override void  OnReverse()
        {
            var sourcePile = CardGame.PileAt(TargetLocation);
            var targetPile = CardGame.PileAt(Location);

            var pile = sourcePile.SubPile(TargetLocation.Index, TargetLocation.Index + _totalMoved);
            pile.Invert();

            targetPile.InsertCards(Location.Index, pile);
            sourcePile.RemoveCards(TargetLocation.Index, pile.Count);
        }
    }

    public class ResetStockAction : IncrementDealCountAction
    {
        private readonly MovePileAction _moveAction;
        private int _previousStackLimit;

        public ResetStockAction(CardGame cardGame, PartLocation from, PartLocation to) : base(cardGame, from)
        {
            _moveAction = new MovePileAction(cardGame, from, to);
        }
    
        public CardPile TargetPile
        {
            get
            {
                return _moveAction.TargetPile;
            }
        }
    
        protected override void OnExecute()
        {
            _previousStackLimit = _moveAction.SourcePile.StackLimit;

            base.OnExecute();

            _moveAction.SourcePile.StackLimit = 0;
            _moveAction.PileBeingMoved.Invert();
            _moveAction.Execute();
        }

        protected override void OnReverse()
        {
            base.OnReverse();

            _moveAction.SourcePile.StackLimit = _previousStackLimit;
            _moveAction.PileBeingMoved.Invert();
            _moveAction.Reverse();
        }
    }
}
